#ifndef V2_NIM_STORAGE_SERVICE_H
#define V2_NIM_STORAGE_SERVICE_H
#include "v2_nim_internal.hpp"
namespace v2 {
/// @brief 存储服务
/// @pre
/// 调用 `V2NIMClient::get()` 拿到 client 实例
/// 调用 `client.getStorageService()` 拿到 storageService 实例
/// @par 示例代码
/// @code
/// auto& client = V2NIMClient::get();
/// auto& messageService = client.getStorageService();
/// @endcode
class V2NIMStorageService {
public:
    /// @brief 添加自定义存储场景, 需在登录前调用
    /// @param sceneName 自定义存储场景
    /// @return void
    /// @par 示例代码
    /// @code
    /// storageService.addCustomStorageScene("customScene", 0); // never expire
    /// @endcode
    virtual void addCustomStorageScene(nstd::string sceneName, uint64_t expireTime) = 0;

    /// @brief 创建文件上传任务
    /// @param fileParams 文件上传的相关参数
    /// @return V2NIMUploadFileTask
    /// @par 示例代码
    /// @code
    /// V2NIMUploadFileParams fileParams;
    /// fileParams.filePath = "~/test.txt";
    /// fileParams.name = "hello.txt";
    /// fileParams.scene = "customScene";
    /// auto uploadTask = storageService.createUploadFileTask(fileParams);
    /// @endcode
    virtual V2NIMUploadFileTask createUploadFileTask(V2NIMUploadFileParams fileParams) = 0;

    /// @brief 文件上传
    /// @param fileParams 文件上传的相关参数
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @param progress 上传进度回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMUploadFileParams fileParams;
    /// fileParams.filePath = "~/test.txt";
    /// fileParams.name = "hello.txt";
    /// fileParams.scene = "customScene";
    /// auto uploadTask = storageService.createUploadFileTask(fileParams);
    /// storageService.uploadFile(
    ///     uploadTask,
    ///     [](nstd::string url) {
    ///         // upload file succeeded
    ///     },
    ///     [](V2NIMError error) {
    ///         // upload file failed, handle error
    ///     },
    ///     [](uint32_t progress) {
    ///         // upload progress
    ///     });
    /// @endcode
    virtual void uploadFile(V2NIMUploadFileTask fileTask,
        V2NIMSuccessCallback<nstd::string> success,
        V2NIMFailureCallback failure,
        V2NIMProgressCallback progress) = 0;

    /// @brief 取消文件上传
    /// @param uploadId 文件上传任务 id
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMUploadFileTask fileTask;
    /// // uploadFile
    /// // ...
    /// storageService.cancelUploadFile(
    ///     fileTask,
    ///     []() {
    ///         // cancel upload file succeeded
    ///     },
    ///     [](V2NIMError error) {
    ///         // cancel upload file failed, handle error
    ///     });
    /// @endcode
    virtual void cancelUploadFile(V2NIMUploadFileTask fileTask, V2NIMSuccessCallback<void> success, V2NIMFailureCallback failure) = 0;

    /// @brief 下载文件
    /// @param url 文件 URL
    /// @param savePath 文件保存路径
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @param progress 下载进度回调
    /// @return nstd::string 下载任务 ID
    /// @par 示例代码
    /// @code
    /// storageService.downloadFile(
    ///     "https://example.com/test.txt",
    ///     "~/test.txt",
    ///     [](const nstd::string& url) {
    ///         // download file succeeded
    ///     },
    ///     [](V2NIMError error) {
    ///         // download file failed, handle error
    ///     },
    ///     [](uint32_t progress) {
    ///         // download progress
    ///     });
    /// @endcode
    virtual void downloadFile(const nstd::string& url,
        const nstd::string& savePath,
        V2NIMSuccessCallback<nstd::string> success,
        V2NIMFailureCallback failure,
        V2NIMProgressCallback progress) = 0;

    /// @brief 取消下载任务
    /// @param url 下载地址，SDK 内部会根据下载地址决定取消哪个任务
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// storageService.cancelDownloadFile(https://example.com/test.txt, []() {
    ///     // cancel download file succeeded
    /// }, [](V2NIMError error) {
    ///     // cancel download file failed, handle error
    /// });
    /// @endcode
    virtual void cancelDownloadFile(const nstd::string& url, V2NIMSuccessCallback<void> success, V2NIMFailureCallback failure) = 0;

    /// @brief 查询存储场景列表
    /// @return nstd::vector<V2NIMStorageScene>
    /// @par 示例代码
    /// @code
    /// auto sceneList = storageService.getStorageSceneList();
    /// @endcode
    virtual nstd::vector<V2NIMStorageScene> getStorageSceneList() = 0;

    /// @brief 短链接转长链接
    /// @param url 文件远程地址
    /// @param success 链接转换成功的回调
    /// @param failure 链接转换失败的回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// storageService.shortUrlToLong("https://example.com/short?_im_url=1", [](nstd::string url) {
    ///     // short url to long succeeded
    /// }, [](V2NIMError error) {
    ///     // short url to long failed, handle error
    /// });
    /// @endcode
    virtual void shortUrlToLong(const nstd::string& url, V2NIMSuccessCallback<nstd::string> success, V2NIMFailureCallback failure) = 0;

    /// @brief 下载消息附件
    /// @param downloadParam 下载参数 {@link V2NIMDownloadMessageAttachmentParams}
    /// @param success 成功回调，携带下载成功后的本地文件路径
    /// @param failure 失败回调
    /// @param progress 下载进度回调
    /// @par 示例代码
    /// @code
    /// V2NIMDownloadMessageAttachmentParams downloadParam;
    /// downloadParam.attachment = attachment;
    /// downloadParam.type = V2NIM_DOWNLOAD_ATTACHMENT_TYPE_SOURCE;
    /// storageService.downloadAttachment(
    ///     downloadParam,
    ///     [](const nstd::string& path) {
    ///         // download attachment succeeded
    ///     },
    ///     [](V2NIMError error) {
    ///         // download attachment failed, handle error
    ///     },
    ///     [](uint32_t progress) {
    ///         // download progress
    ///     });
    /// @endcode
    virtual void downloadAttachment(const V2NIMDownloadMessageAttachmentParams& downloadParam,
        const V2NIMSuccessCallback<const nstd::string&>& success,
        const V2NIMFailureCallback& failure,
        const V2NIMProgressCallback& progress) = 0;

    /// @brief 获取图片消息中的图片缩略图
    /// @param attachment 消息附件
    /// @param thumbSize 图片缩略图的尺寸，若不指定则使用默认 150x150
    /// @param success 成功回调，携带图片缩略图的 URL
    /// @param failure 失败回调
    /// @par 示例代码
    /// @code
    /// storageService.getImageThumbUrl(attachment, V2NIMSize(150, 150), [](const V2NIMGetMediaResourceInfoResult& result) {
    ///         // get image thumb url succeeded
    ///     }, [](V2NIMError error) {
    ///         // get image thumb url failed, handle error
    ///     });
    /// @endcode
    virtual void getImageThumbUrl(const nstd::shared_ptr<V2NIMMessageAttachment>& attachment,
        const nstd::optional<V2NIMSize>& thumbSize,
        const V2NIMSuccessCallback<const V2NIMGetMediaResourceInfoResult&>& success,
        const V2NIMFailureCallback& failure) = 0;

    /// @brief 获取视频消息中的视频封面
    /// @param attachment 消息附件
    /// @param thumbSize 视频封面的尺寸，若不指定则使用默认 150x150
    /// @param success 成功回调，携带视频封面的 URL
    /// @param failure 失败回调
    /// @par 示例代码
    /// @code
    /// storageService.getVideoCoverUrl(attachment, V2NIMSize(150, 150), [](const V2NIMGetMediaResourceInfoResult& result) {
    ///        // get video cover url succeeded
    ///    }, [](V2NIMError error) {
    ///        // get video cover url failed, handle error
    ///    });
    /// @endcode
    virtual void getVideoCoverUrl(const nstd::shared_ptr<V2NIMMessageAttachment>& attachment,
        const nstd::optional<V2NIMSize>& thumbSize,
        const V2NIMSuccessCallback<const V2NIMGetMediaResourceInfoResult&>& success,
        const V2NIMFailureCallback& failure) = 0;
};

}  // namespace v2

#endif
